#include "client.h"
#define CONVERSION_NUM 1024 // 内存单位进制转化

void getsCommand(int sockfd, train_t * pt) {
    /* 获取文件名字 */
    // char filename[20] = {0};
    // strcpy(filename, pt->buff);
    
    //先判断是否存在文件
    if(access(pt->buff, F_OK) == 0){
        //存在
        breakPoint_gets(sockfd, pt);
    } else {
        printf("不存在\n");

        int exit_flag = 0;
        sendn(sockfd, &exit_flag, sizeof(exit_flag));

        // 打开文件
        int fd = open(pt->buff, O_RDWR | O_CREAT | O_TRUNC, 0644);
        if(fd < 0) { perror("open"); return; }

        // 获取文件内容大小
        off_t len = 0;
        int ret = recvn(sockfd, &len, sizeof(len));
        if ( ret < 0  ) { perror( "recv" ); close(fd);  return; }
        printf("file content size is %ld\n", len);

        // @zg 判断文件是否大于100MB, 若大于100MB则进行mmap零拷贝传输
        ret = 0;
        long size_in_mb = len / (CONVERSION_NUM * CONVERSION_NUM);
        if (size_in_mb > 100) {
            // 制造文件空洞
            ftruncate(fd, len);

            // 接收文件
            char* pMap = (char*)mmap(NULL, len, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
            ret = recvn(sockfd, pMap, len);

            if ( ret == 0 ) { return; }

            //接收完成
            printf("file recv over.\n");
            munmap(pMap, len);
            close(fd);
            return;
        }
        // @zg 小文件处理流程
        //接收并写入文件
        char buff[1000] = {0};
        off_t left = len;
        while(left > 0) {
            if(left < 1000) {
                ret = recvn(sockfd, buff, left);
            } else {
                ret = recvn(sockfd, buff, sizeof(buff));
            }
            if(ret < 0) {
                break;
            }
            ret = write(fd, buff, ret);
            left -= ret;
        }
        close(fd);
    }
}

